package com.winway.framework.sap.service.impl;

import com.sap.conn.jco.*;
import com.winway.common.exception.BusinessException;
import com.winway.framework.sap.client.SAPWebServiceClient;
import com.winway.framework.sap.client.ZBF_MASTERStub;
import com.winway.framework.sap.config.SapConstant;
import com.winway.framework.sap.model.SapDeptModel;
import com.winway.framework.sap.model.SystemUser;
import com.winway.framework.sap.service.SapService;
import com.winway.framework.sap.util.SapConnUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * sap相关接口实现类
 *
 * @author yhf
 * @date 2022-04-21
 */
@Slf4j
@Service
public class SapServiceImpl implements SapService {

    @Override
    public List<SystemUser> getUserListByDept(List<String> deptIdList) {
        if (CollectionUtils.isEmpty(deptIdList)) {
            return null;
        }
        JCoDestination destination = SapConnUtils.connect();
        JCoFunction jcoFunction;
        try {
            log.info("sap获取函数，函数名：{}", SapConstant.FUNCTION_ZHR_STRUCTURE);
            jcoFunction = destination.getRepository().getFunction(SapConstant.FUNCTION_ZHR_STRUCTURE);
        } catch (Exception e) {
            log.error("sap获取函数失败，错误信息：{}", e.getMessage());
            throw new BusinessException("sap函数获取失败");
        }
        List<SystemUser> sapUserList = new ArrayList<>();
        JCoTable userData = null, deptData = null;
        for (String deptId : deptIdList) {
            jcoFunction.getImportParameterList().setValue(SapConstant.PARAM_ZHR_STRUCTURE_OBJID, deptId);
            try {
                log.info("调用sap【{}】函数，查询参数：{}", SapConstant.FUNCTION_ZHR_STRUCTURE, deptId);
                jcoFunction.execute(destination);
            } catch (Exception e) {
                log.error("调用sap【{}】函数失败，查询参数：{}，错误信息：{}", SapConstant.FUNCTION_ZHR_STRUCTURE, deptId, e.getMessage());
                throw new BusinessException("sap调用函数失败");
            }
            JCoParameterList jcoParameterList = jcoFunction.getTableParameterList();
            // 获取对应的数据,部门的数据：BM2，岗位的数据：GW2，人员的数据：RY2
            userData = jcoParameterList.getTable(SapConstant.TABLE_ZHR_STRUCTURE_RY2);
            deptData = jcoParameterList.getTable(SapConstant.TABLE_ZHR_STRUCTURE_BM2);
        }
        log.info("从sap获取数据结束，开始组装数据...");
        // 部门数据转化
        // 部门名称map，key为部门id，value为部门全路径名称
        Map<String, String> deptNameMap = jcoDeptDataConvert(deptData, deptIdList);
        // 人员数据转换
        jcoDataDeal(sapUserList, userData, deptNameMap);
        return sapUserList;
    }

    @Override
    public ZBF_MASTERStub.ZbfMaster[] zbfMasterFunction(String[] params) {
        List<String> list2 = Arrays.asList(params);
        SAPWebServiceClient client = new SAPWebServiceClient();
        try {
            log.info("调用zbfMaster函数，参数：{}", Arrays.toString(list2.toArray()));
            ZBF_MASTERStub.ZbfMaster[] zbfMasters = client.SAPMasterWebServiceInit(list2);
            log.info("调用成功，获取{}条数据", zbfMasters == null ? 0 : zbfMasters.length);
            return zbfMasters;
        } catch (Exception e) {
            log.error("调用异常：{}", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    private Map<String, String> jcoDeptDataConvert(JCoTable dataOut, List<String> ceilDeptIdList) {
        List<SapDeptModel> deptList = new ArrayList<>();
        if (dataOut != null && dataOut.getNumRows() > 0) {
            for (int j = 0; j < dataOut.getNumRows(); j++) {
                dataOut.setRow(j);
                JCoMetaData md = dataOut.getMetaData();
                int columnCount = md.getFieldCount();
                SapDeptModel dept = new SapDeptModel();
                for (int i = 0; i < columnCount; i++) {
                    if ("STEXT".equalsIgnoreCase(md.getName(i))) {
                        dept.setName(dataOut.getValue(i).toString());
                    } else if ("SOBID".equalsIgnoreCase(md.getName(i))) {
                        dept.setCode(dataOut.getValue(i).toString());
                    } else if ("OBJID".equalsIgnoreCase(md.getName(i))) {
                        dept.setPCode(dataOut.getValue(i).toString());
                    }
                }
                deptList.add(dept);
            }
        }
        // 循环获取部门全路径名称
        // 部门编号为key，名称为value
        Map<String, String> codeNameMap = deptList.stream().collect(Collectors.toMap(SapDeptModel::getCode, SapDeptModel::getName));
        // 部门编号为key，上级部门编号为value
        Map<String, String> map = deptList.stream().collect(Collectors.toMap(SapDeptModel::getCode, SapDeptModel::getPCode));
        for (SapDeptModel dept : deptList) {
            // 如果自己就是顶层部门
            String code = dept.getCode();
            if (ceilDeptIdList.contains(code)) {
                dept.setRouteName(dept.getName());
                continue;
            }
            // 自己不是顶层部门，获取全路径
            String routeName = dept.getName();
            do {
                code = map.get(code);
                routeName = codeNameMap.get(code).concat("_").concat(routeName);
            } while (!ceilDeptIdList.contains(code));
            dept.setRouteName(routeName);
        }
        return deptList.stream().collect(Collectors.toMap(SapDeptModel::getCode, SapDeptModel::getRouteName));
    }

    private void jcoDataDeal(List<SystemUser> rowDatas, JCoTable dataOut, Map<String, String> deptNameMap) {
        Set<String> jobNumSet = new HashSet<>();
        if (dataOut != null && dataOut.getNumRows() > 0) {
            out:
            for (int j = 0; j < dataOut.getNumRows(); j++) {
                dataOut.setRow(j);
                JCoMetaData md = dataOut.getMetaData();
                int columnCount = md.getFieldCount();
                SystemUser user = new SystemUser();
                for (int i = 0; i < columnCount; i++) {
                    if ("PERNR".equalsIgnoreCase(md.getName(i))) {
                        // 用户工号
                        String jobNum = dataOut.getValue(i).toString();
                        if (jobNumSet.contains(jobNum)) {
                            continue out;
                        }
                        jobNumSet.add(jobNum);
                        user.setJobNum(jobNum);
                    } else if ("SNAME".equalsIgnoreCase(md.getName(i))) {
                        // 用户名称
                        user.setName(dataOut.getValue(i).toString());
                    } else if ("RUFNM".equalsIgnoreCase(md.getName(i))) {
                        // 用户英文名
                        user.setAnotherName(dataOut.getValue(i).toString());
                    } else if ("SOBID".equalsIgnoreCase(md.getName(i))) {
                        user.setDeptCode(dataOut.getValue(i).toString());
                    }
                }
                user.setDeptName(deptNameMap.get(user.getDeptCode()));
                rowDatas.add(user);
            }
        }
    }
}
